package com.lifeverse.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lifeverse.entity.LifeEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 生命体WebSocket控制器
 * 处理生命体实时更新的WebSocket连接
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class LifeEntityWebSocketController implements WebSocketHandler {

    private final ObjectMapper objectMapper;
    
    // 存储所有活跃的WebSocket会话
    private final CopyOnWriteArraySet<WebSocketSession> sessions = new CopyOnWriteArraySet<>();
    
    // 存储会话的元数据
    private final Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("Life entity WebSocket connection established: {}", session.getId());
        sessions.add(session);
        sessionMap.put(session.getId(), session);
        
        // 发送连接成功消息
        sendMessage(session, Map.of(
            "type", "CONNECTION_ESTABLISHED",
            "sessionId", session.getId(),
            "timestamp", System.currentTimeMillis()
        ));
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        try {
            String payload = message.getPayload().toString();
            log.debug("Received WebSocket message from {}: {}", session.getId(), payload);
            
            // 解析消息
            Map<String, Object> messageData = objectMapper.readValue(payload, Map.class);
            String messageType = (String) messageData.get("type");
            
            // 处理心跳消息
            if ("PING".equals(messageType)) {
                sendMessage(session, Map.of(
                    "type", "PONG",
                    "timestamp", System.currentTimeMillis()
                ));
            }
            
        } catch (Exception e) {
            log.error("Error handling WebSocket message from {}: {}", session.getId(), e.getMessage());
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.error("WebSocket transport error for session {}: {}", session.getId(), exception.getMessage());
        removeSession(session);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        log.info("Life entity WebSocket connection closed: {} with status: {}", session.getId(), closeStatus);
        removeSession(session);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 移除会话
     */
    private void removeSession(WebSocketSession session) {
        sessions.remove(session);
        sessionMap.remove(session.getId());
    }

    /**
     * 发送消息给指定会话
     */
    private void sendMessage(WebSocketSession session, Object message) {
        try {
            if (session.isOpen()) {
                String jsonMessage = objectMapper.writeValueAsString(message);
                session.sendMessage(new TextMessage(jsonMessage));
            }
        } catch (IOException e) {
            log.error("Error sending WebSocket message to {}: {}", session.getId(), e.getMessage());
            removeSession(session);
        }
    }

    /**
     * 广播消息给所有连接的客户端
     */
    public void broadcastMessage(Object message) {
        log.debug("Broadcasting message to {} sessions", sessions.size());
        
        sessions.forEach(session -> {
            try {
                sendMessage(session, message);
            } catch (Exception e) {
                log.error("Error broadcasting message to session {}: {}", session.getId(), e.getMessage());
                removeSession(session);
            }
        });
    }

    /**
     * 广播生命体创建事件
     */
    public void broadcastEntityCreated(LifeEntity entity) {
        Map<String, Object> event = Map.of(
            "type", "ENTITY_CREATED",
            "entityId", entity.getId().toString(),
            "entity", entity,
            "timestamp", System.currentTimeMillis()
        );
        broadcastMessage(event);
    }

    /**
     * 广播生命体更新事件
     */
    public void broadcastEntityUpdated(LifeEntity entity) {
        Map<String, Object> event = Map.of(
            "type", "ENTITY_UPDATED",
            "entityId", entity.getId().toString(),
            "entity", entity,
            "timestamp", System.currentTimeMillis()
        );
        broadcastMessage(event);
    }

    /**
     * 广播生命体删除事件
     */
    public void broadcastEntityDeleted(Long entityId, String entityName) {
        Map<String, Object> event = Map.of(
            "type", "ENTITY_DELETED",
            "entityId", entityId.toString(),
            "entityName", entityName,
            "timestamp", System.currentTimeMillis()
        );
        broadcastMessage(event);
    }

    /**
     * 广播生命体状态变更事件
     */
    public void broadcastStatusChanged(LifeEntity entity, String oldStatus, String newStatus) {
        Map<String, Object> event = Map.of(
            "type", "STATUS_CHANGED",
            "entityId", entity.getId().toString(),
            "entity", entity,
            "oldStatus", oldStatus,
            "newStatus", newStatus,
            "timestamp", System.currentTimeMillis()
        );
        broadcastMessage(event);
    }

    /**
     * 获取当前连接数
     */
    public int getConnectionCount() {
        return sessions.size();
    }

    /**
     * 获取所有会话ID
     */
    public String[] getSessionIds() {
        return sessionMap.keySet().toArray(new String[0]);
    }
}